import { NestFactory } from '@nestjs/core'
import {
  ExpressAdapter,
  NestExpressApplication
} from '@nestjs/platform-express'
import { ConfigService } from '@nestjs/config'
import { SwaggerModule } from '@nestjs/swagger'
import {
  WinstonLogger,
  WinstonModule,
  WINSTON_MODULE_LOGGER
} from '@ttou/nest-winston'
import SwaggerStats from 'swagger-stats'
import { AppModule } from './app.module'
import { loggerOptions } from './config'

async function bootstrap() {
  const httpAdapter = new ExpressAdapter()
  const app = await NestFactory.create<NestExpressApplication>(
    AppModule,
    httpAdapter,
    {
      logger: WinstonModule.createLogger(loggerOptions)
    }
  )

  const configService = app.get(ConfigService)
  const appPort = configService.get<number>('port')
  const appPrefix = configService.get<string>('prefix')
  const staticPath = configService.get<string>('static.path')

  // 获取日志服务
  const logger = app.get<WinstonLogger>(WINSTON_MODULE_LOGGER)

  // 应用配置
  app.setGlobalPrefix(appPrefix)
  app.useStaticAssets(staticPath)
  app.useLogger(logger)

  // 文档配置
  const swaggerPath = configService.get<string>('swagger.path')
  const swaggerConfig = configService.get<any>('swagger.config')
  const document = SwaggerModule.createDocument(app, swaggerConfig)
  SwaggerModule.setup(swaggerPath, app, document)

  // 访问记录
  const statsPath = configService.get<string>('swagger.statsPath')
  app.use(
    SwaggerStats.getMiddleware({
      swaggerSpec: document,
      swaggerOnly: true,
      uriPath: statsPath
    })
  )

  await app.listen(appPort, () => {
    logger.log(
      `Nest application is running at http://localhost:${appPort}`,
      'NestApplication'
    )
    logger.log(
      `Swagger is running at http://localhost:${appPort}${swaggerPath}`,
      'NestApplication'
    )
    logger.log(
      `Swagger stats is running at http://localhost:${appPort}${statsPath}`,
      'NestApplication'
    )
  })
}
bootstrap()
